#pragma once

#include <iostream>
#include <string>
// #include <jsoncpp/json/json.h>

// #define MySelf 1

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

// 将输入的字符串内容封装为数据包，格式为 "长度\n内容\n"
std::string Encode(std::string &content)
{
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

// 从数据包中提取内容，存入content指针，并移除已处理部分
bool Decode(std::string &package, std::string *content)
{
    std::size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos)
        return false;
    std::string len_str = package.substr(0, pos);
    std::size_t len = std::stoi(len_str);
    std::size_t total_len = len_str.size() + len + 2;
    if (package.size() < total_len)
        return false;

    *content = package.substr(pos + 1, len);
    package.erase(0, total_len);

    return true;
}

// Request req(2, 3, '+')
class Request
{
public:
    // 构造函数：初始化操作数x、y和运算符op
    Request(int data1, int data2, char oper) : x(data1), y(data2), op(oper) {}

    // 默认构造函数
    Request() {}

public:
    //1.客户端发起请求，将内容序列化发送给服务端
    // 将Request对象序列化为字符串，存入out，返回true表示成功  x op y
    bool Serialize(std::string *out)
    {
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
        return true;
    }

    //2.服务端接受到客户的序列化请求，反序列化拿到内容
    // 从字符串in反序列化出x、y和op，填充到Request对象，返回true表示成功
    bool Deserialize(const std::string &in)
    {
        // 找到x
        std::size_t left = in.find(blank_space_sep);
        if (left == std::string::npos)
            return false;
        std::string part_x = in.substr(0, left);

        // 找到y
        std::size_t right = in.rfind(blank_space_sep);
        if (right == std::string::npos)
            return false;
        std::string part_y = in.substr(right + 1);

        if (left + 2 != right)
            return false;
        op = in[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);
        return true;
    }

    // 打印Request对象的调试信息，格式为"x op y=?"
    void DebugPrint()
    {
        std::cout << "新请求构建完成:  " << x << op << y << "=?" << std::endl;
    }

public:
    int x;
    int y;
    char op; // + - * / %
};

class Response
{
public:
    // 构造函数：初始化计算结果result和状态码code
    Response(int res, int c) : result(res), code(c) {}

    // 默认构造函数
    Response() {}

public:
    //3.服务端将运行后的结果序列化发送给客户端
    // 将Response对象序列化为字符串，存入out，返回true表示成功
    // "result code"
    // 构建报文的有效载荷
    bool Serialize(std::string *out)
    {
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *out = s;
        return true;
    }

    //4.客户端将结果反序列化，拿到内容
    // 从字符串in反序列化出result和code，填充到Response对象，返回true表示成功
    bool Deserialize(const std::string &in) // "result code"
    {
        std::size_t pos = in.find(blank_space_sep);
        if (pos == std::string::npos)
            return false;
        std::string part_left = in.substr(0, pos);
        std::string part_right = in.substr(pos + 1);

        result = std::stoi(part_left);
        code = std::stoi(part_right);

        return true;
    }

    // 打印Response对象的调试信息，格式为"结果响应完成, result: X, code: Y"
    void DebugPrint()
    {
        std::cout << "结果响应完成, result: " << result << ", code: "<< code << std::endl;
    }

public:
    int result;
    int code; // 0表示成功，非0表示错误原因
};